/*
 * @Author: 一盏青灯欲锁魂
 * @Date: 2021-06-15 16:23:16
 * @LastEditTime: 2021-06-25 10:36:13
 * @Description: 全局模块整流层
 * @FilePath: \nest_demo\src\app.module.ts
 */
import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './tools/middleware/logger.middleware';
import { HelloModule } from './module/hello/hello.module';
import { IndexModule } from './module/index/index.module';
import { ExceptionModule } from './module/exception/exception.module';
import { PipeModule } from './module/pipe/pipe.module';
import { RoleGuardModule } from './module/role_guard/role_guard.module';
import { EmailModule } from './module/email/email.module';
import { MailerModule } from '@nestjs-modules/mailer';
import { resolve } from 'path';
import { ConfigModule, ConfigService } from 'nestjs-config';
import { StatusMonitorModule } from 'nest-status-monitor';
import statusMonitorConfig from './config/statusMonitor';
import { AuthModule } from './module/auth/auth.module';
import { UserModule } from './module/user/user.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ScheduleModule } from '@nestjs/schedule';
import { TimingModule } from './timing/timing.module';
import { AudioModule } from './queue/audio.module';

/*
  * 1. 中间件使用方法：
  *     1. 从'@nestjs/common'核心库中引入'MiddlewareConsumer'、'RequestMethod'
  *     2. 引入定义好的中间件'LoggerMiddleware'
  *     3. AppModule中内置了'configure'属性方法，用以配置中间件
  *     4. configure()接收一个类型为'MiddlewareConsumer'的中间件
  *     
  * 2. consumer讲解：
  *     - .apply() 用于配置指定中间件，所接收的参数就是所需要调用并配置的中间件
  *     - .exclude() 用于排除中间作用的范围，示例是表示排除'/hello'路径下的所有POST请求方法
  *     - .forRoutes() 用于配置监听的主路由，所接收的参数就是需要监听的路由
  * 
  * 注意：
  *     1. forRoutes() 所配置的路由在中间件从会被认为主路由，其下面所有子路由同样也会被监听到
  *       - 比如：localhost:3000/hello/test -> 也会被监听到
*/

/*
  * 邮件服务使用步骤：
  *   1. 引入'MailerModule','join','PugAdapter'
  *   2. 调用MailerModule.forRootAsync()方法，内部useFactory()工厂函数返回邮件配置信息
  *   3. 在nest-cli.json中新增配置，详见"compilerOptions"字段配置
*/ 

/*
  * 项目配置文件管理：
  *   1. 安装nest/config依赖库
  *   2. 导入'ConfigModule'、'ConfigService', 并同时抽离配置信息单独行成一个配置文件，详见config文件夹下email.ts文件
  *   3. 通过ConfigModule.load()加载config文件夹下所有配置文件
  *   4. 在通过ConfigService数据类型参数中.get()方法获取指定名称的配置文件
  *   5. 最后inject注入ConfigService服务
*/


/*
  * 服务监控：
  *   1. 安装nest-status-monitor依赖库，npm install nest-status-monitor --save
  *   2. 引入'StatusMonitorModule'，并书写其配置文件
  *   3. 引入自定义配置文件并在@Module()中注入此服务
*/

/*
  * 定时任务：
  *   1. 从'@nestjs/schedule'中引入'ScheduleModule'，并注入到imports中去
  *   2. 再在imports中注入定义任务模块
*/ 

@Module({
  imports: [
    ConfigModule.load(resolve(__dirname,'config','**/!(*.d).{ts,js}')),
    MailerModule.forRootAsync({
      useFactory:(config:ConfigService)=> config.get('email'),
      inject:[ConfigService]
    }),

    // @nestjs/terminus 使用方式基本一致
    // StatusMonitorModule.setUp(statusMonitorConfig),

    TypeOrmModule.forRootAsync({
      useFactory:(config:ConfigService) => config.get('database'),
      inject:[ConfigService]
    }),

    // ScheduleModule.forRoot(),
    // TimingModule,

    HelloModule, IndexModule, ExceptionModule, PipeModule, RoleGuardModule, EmailModule, AuthModule, UserModule, AudioModule],
  controllers: [],
  providers: [],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware)
      .exclude({ path: 'hello', method: RequestMethod.POST })
      .forRoutes('hello');
  }
}
